<template>
  <div class="chat-container">
    <el-row :gutter="10">
      <!-- 联系人列表 -->
      <el-col :span="4">
        <el-card class="contact-list">
          <template #header>
            <div class="card-header">
              <span>联系人</span>
              <el-button type="primary" size="small" @click="showAddContact = true">
                添加联系人
              </el-button>
            </div>
          </template>
          <el-input
            v-model="searchQuery"
            placeholder="搜索联系人"
            prefix-icon="Search"
            clearable
          />
          <el-scrollbar height="calc(100vh - 340px)">
            <div
              v-for="friend in filteredContacts"
              :key="friend.userId"
              class="contact-item"
              :class="{ active: currentContact?.userId === friend.userId }"
              @click="selectContact(friend)"
            >
              <el-avatar :size="40" :src="userAvatar" />
              <div class="contact-info">
                <div class="contact-name">{{ friend.username }}</div>
              </div>
            </div>
          </el-scrollbar>
        </el-card>
      </el-col>

      <!-- 聊天区域 -->
      <el-col :span="14">
        <el-card class="chat-area">
          <template #header>
            <div class="chat-header">
              <div class="contact-info">
                <el-avatar :size="40" :src="userAvatar" />
                <div class="contact-name">
                  {{ currentContact ? currentContact.username : '请选择联系人' }}
                </div>
              </div>
            </div>
          </template>
          
          <!-- 聊天消息列表 -->
          <div v-if="currentContact" class="message-list" ref="messageList">
            <div
              v-for="msg in messages"
              :key="msg.id"
              class="message-item"
              :class="{ 'message-mine': msg.isMine }"
            >
              <el-avatar :size="36" :src="userAvatar" />
              <div class="message-content">
                <div class="message-text">{{ msg.content }}</div>
                <div class="message-time">{{ formatTime(msg.time) }}</div>
              </div>
            </div>
          </div>

          <!-- 消息输入框 -->
          <div v-if="currentContact" class="message-input">
            <el-input
              v-model="newMessage"
              placeholder="输入消息..."
              @keyup.enter="sendMessage"
            />
            <div class="input-actions">
              <el-button type="primary" @click="sendMessage">
                发送
              </el-button>
            </div>
          </div>
        </el-card>
      </el-col>

      <!-- 端到端加密说明 -->
      <el-col :span="6">
        <el-card class="e2ee-info">
          <template #header>
            <div class="card-header">
              <span class="header-title">端到端加密说明</span>
            </div>
          </template>
          <div class="info-content">
            <ol>
              <li>
                <strong>密钥初始化</strong>
                <p>在首页进行协议初始化，生成身份密钥、签名预共享密钥和预共享密钥。</p>
              </li>
              <li>
                <strong>会话建立</strong>
                <p>发起会话时，系统会自动进行以下步骤：</p>
                <ul>
                  <li>创建会话ID和会话方ID</li>
                  <li>初始化双方的协议</li>
                  <li>创建粘性会话</li>
                  <li>生成并存储发送密钥</li>
                </ul>
              </li>
              <li>
                <strong>消息加密</strong>
                <p>发送消息时：</p>
                <ul>
                  <li>使用发送密钥对消息进行加密</li>
                  <li>通过WebSocket发送加密后的消息</li>
                  <li>接收方使用对应的密钥进行解密</li>
                </ul>
              </li>
            </ol>
            <div class="security-tips">
              <el-alert
                title="安全提示"
                type="info"
                :closable="false"
                show-icon
              >
                <p>1. 所有消息都经过端到端加密，只有通信双方可以解密</p>
                <p>2. 每次会话都使用新的密钥，确保前向安全性</p>
                <p>3. 密钥不会存储在服务器，确保通信安全</p>
              </el-alert>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 添加联系人对话框 -->
    <el-dialog v-model="showAddContact" title="添加联系人" width="400px">
      <el-form :model="newContact" label-width="80px">
        <el-form-item label="用户名">
          <el-input v-model="newContact.username" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showAddContact = false">取消</el-button>
          <el-button type="primary" @click="addContact">添加</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick, computed } from 'vue';
import { ElMessage } from 'element-plus';
import { Search } from '@element-plus/icons-vue';
import axios from 'axios';
import { initWebSocket, setMessageHandler, sendSocketMessage } from '@/views/websocket';

interface Message {
  id: number;
  content: string;
  time: Date;
  isMine: boolean;
}

interface WebSocketMessage {
  senderId: string;
  sessionId: string;
  cipher: string;
  isSticky: boolean;
}

interface EncryptionSenderKeyResponse {
  senderKey: string;
  identityKeyId: number;
  sessionId: string;
  ofUserId: string;
}

interface Friend {
  userId: string;
  username: string;
}

// 创建 axios 实例
const api = axios.create({
  baseURL: '/api',
  timeout: 5000
});

// 添加请求拦截器
api.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// 基础数据
const searchQuery = ref('');
const showAddContact = ref(false);
const currentContact = ref<Friend | null>(null);
const friends = ref<Friend[]>([]);
const newContact = ref({ username: '' });
const userAvatar = ref('https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png');
const messages = ref<Message[]>([]);
const newMessage = ref('');
const messageList = ref<HTMLElement>();

// 过滤联系人
const filteredContacts = computed(() => {
  if (!searchQuery.value) return friends.value;
  return friends.value.filter(friend =>
    friend.username.toLowerCase().includes(searchQuery.value.toLowerCase())
  );
});

// 加载好友列表
const loadFriends = async () => {
  try {
    const response = await api.get('/user/getFriends');
    if (response.data?.data?.records) {
      friends.value = response.data.data.records;
    }
  } catch (error) {
    ElMessage.error('获取好友列表失败');
  }
};

// 选择联系人
const selectContact = (friend: Friend) => {
  currentContact.value = friend;
  // 从本地存储加载聊天记录
  const chatHistory = localStorage.getItem(`chat_history_${friend.userId}`);
  if (chatHistory) {
    messages.value = JSON.parse(chatHistory).map((msg: any) => ({
      ...msg,
      time: new Date(msg.time)
    }));
  } else {
    messages.value = [];
  }
  nextTick(scrollToBottom);

  // 清除该用户的待处理消息
  const pendingItems = JSON.parse(localStorage.getItem('pending_items') || '[]');
  const updatedItems = pendingItems.filter((item: any) => item.senderId !== friend.userId);
  localStorage.setItem('pending_items', JSON.stringify(updatedItems));
};

// 添加联系人
const addContact = async () => {
  try {
    await api.post('/user/addFriend', {
      username: newContact.value.username
    });
    ElMessage.success('添加成功');
    showAddContact.value = false;
    loadFriends();
  } catch (error) {
    ElMessage.error('添加失败');
  }
};

// 处理 WebSocket 消息
const handleSocketMessage = async (message: any) => {
  console.log('处理WebSocket消息:', message);
  
  try {
    // 解密消息
    const decryptResponse = await api.post('/secure/decryptText', {
      senderId: message.senderId,
      sessionId: message.sessionId,
      cipher: message.content,
      isSticky: true
    });

    if (decryptResponse.data.status === 'success') {
      const newMessage = {
        id: Date.now(),
        content: decryptResponse.data.text,
        time: new Date(message.timestamp),
      isMine: false
      };

      // 如果是当前联系人的消息，直接显示
      if (currentContact.value && message.senderId === currentContact.value.userId) {
        messages.value.push(newMessage);
        nextTick(scrollToBottom);
      } else {
        // 存储消息到本地
        const senderId = message.senderId;
        const chatHistory = localStorage.getItem(`chat_history_${senderId}`);
        const history = chatHistory ? JSON.parse(chatHistory) : [];
        history.push(newMessage);
        localStorage.setItem(`chat_history_${senderId}`, JSON.stringify(history));

        // 更新待处理事项
        const pendingItems = JSON.parse(localStorage.getItem('pending_items') || '[]');
        const existingItem = pendingItems.find((item: any) => item.senderId === senderId);
        
        if (existingItem) {
          existingItem.count = (existingItem.count || 0) + 1;
          existingItem.lastMessage = decryptResponse.data.text;
          existingItem.time = new Date().toLocaleString();
        } else {
          // 获取发送者用户名
          const senderResponse = await api.get(`/user/getUsername/${senderId}`);
          const newPendingItem = {
            id: Date.now(),
            type: 'chat',
            title: '新的聊天消息',
            sender: senderResponse.data,
            senderId: senderId,
            count: 1,
            lastMessage: decryptResponse.data.text,
            time: new Date().toLocaleString()
          };
          pendingItems.push(newPendingItem);
        }
        
        localStorage.setItem('pending_items', JSON.stringify(pendingItems));
        console.log('更新后的待处理事项:', pendingItems); // 添加日志
      }
    }
  } catch (error) {
    console.error('处理消息失败:', error);
  }
};

// 发送消息
const sendMessage = async () => {
  if (!newMessage.value.trim() || !currentContact.value) return;
  
  try {
    const user_uuid = localStorage.getItem('user_uuid');
    if (!user_uuid) {
      throw new Error('用户未登录');
    }

    let senderKey: string;
    let identityKeyId: number;
    let sessionId: string;

    //1. 获取SessionId
    const sessionResponse = await api.post('/session/getSessionId', {
      ofUserId: user_uuid,
      forUserId: currentContact.value.userId
    });
    sessionId = sessionResponse.data.data;

    // 1. 检查是否已有加密发送密钥
    const hasKeyResponse = await api.post('/keys/hasDecryptionSenderKey', {
      ofUserId: user_uuid,
      forUserId: currentContact.value.userId,
      sessionId
    });

    if (hasKeyResponse.data.data) {
      // 如果已有密钥，直接获取
      const keyResponse = await api.post<EncryptionSenderKeyResponse>('/keys/getDecryptionSenderKey', {
        ofUserId: user_uuid,
        forUserId: currentContact.value.userId
      });
      senderKey = keyResponse.data.data.senderKey;
      identityKeyId = keyResponse.data.data.identityKeyId;
      sessionId = keyResponse.data.data.sessionId;
    } else {
      // 如果没有密钥，需要生成新的
      // 获取发送密钥
      const [fromSenderKey, toSenderKey] = await Promise.all([
        api.post('/secure/getSenderKey', {
          senderId: user_uuid,
          targetId: currentContact.value.userId,
          sessionId,
          isSticky: true
        }),
        api.post('/secure/getSenderKey', {
          senderId: currentContact.value.userId,
          targetId: user_uuid,
          sessionId,
          isSticky: true
        })
      ]);

      // 获取双方的身份密钥ID
      const [ofUserIdentityKeyId, fromUserIdentityKeyId] = await Promise.all([
        api.post('/keys/getIdentityKeyIdByUserId', {
          userId: user_uuid
        }),
        api.post('/keys/getIdentityKeyIdByUserId', {
          userId: currentContact.value.userId
        })
      ]);

      // 存储加密发送密钥
      await Promise.all([
        api.post('/keys/storeDecryptionSenderKey', {
          senderKey: fromSenderKey.data.data,
          identityKeyId: ofUserIdentityKeyId.data.data,
          sessionId,
          ofUserId: user_uuid,
          forUserId: currentContact.value.userId
        }),
        api.post('/keys/storeDecryptionSenderKey', {
          senderKey: toSenderKey.data.data,
          identityKeyId: fromUserIdentityKeyId.data.data,
          sessionId,
          ofUserId: currentContact.value.userId,
          forUserId: user_uuid
        })
      ]);

      // 初始化粘性会话
      await Promise.all([
        api.post('/secure/initStickySession', {
          senderKey: fromSenderKey.data.data,
          identityKeyId: ofUserIdentityKeyId.data.data,
          sessionId,
          senderId: user_uuid
        }),
        api.post('/secure/initStickySession', {
          senderKey: toSenderKey.data.data,
          identityKeyId: fromUserIdentityKeyId.data.data,
          sessionId,
          senderId: currentContact.value.userId
        })
      ]);

      senderKey = fromSenderKey.data.data;
    }

      
    // 加密消息
    const encryptResponse = await api.post('/secure/encryptText', {
      senderId: user_uuid,
      sessionId,
      text: newMessage.value,
      isSticky: true
    });

    
    const cipherText = encryptResponse.data.cipher;

      // 更新本地消息列表
      const messageObj = {
    id: Date.now(),
    content: newMessage.value,
    time: new Date(),
    isMine: true
    };
  
    messages.value.push(messageObj);
    
    // 存储消息到本地
    const chatHistory = localStorage.getItem(`chat_history_${currentContact.value.userId}`);
    const history = chatHistory ? JSON.parse(chatHistory) : [];
    history.push(messageObj);
    localStorage.setItem(`chat_history_${currentContact.value.userId}`, JSON.stringify(history));

    newMessage.value = '';
    nextTick(scrollToBottom);

    // 发送WebSocket消息
    sendSocketMessage({
      type: 'chatMessage',
      senderId: user_uuid,
      receiverId: currentContact.value.userId,
      sessionId,
      content: cipherText,
      timestamp: messageObj.time
    });

  } catch (error) {
    ElMessage.error('发送消息失败');
    console.error('发送消息失败:', error);
  }
};

// 滚动到底部
const scrollToBottom = () => {
  if (messageList.value) {
    messageList.value.scrollTop = messageList.value.scrollHeight;
  }
};

// 格式化时间
const formatTime = (t: Date) => t.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });

// 在 onMounted 中添加 WebSocket 初始化
onMounted(() => {
  loadFriends();
  initWebSocket();
  
  // 设置消息处理器
  setMessageHandler(handleSocketMessage);

  // 检查是否有从首页跳转过来的联系人
  const currentChatFriendId = localStorage.getItem('currentChatFriendId');
  const currentChatFriendName = localStorage.getItem('currentChatFriendName');
  
  if (currentChatFriendId && currentChatFriendName) {
    // 等待好友列表加载完成
    const checkFriend = setInterval(() => {
      if (friends.value.length > 0) {
        const friend = friends.value.find(f => f.userId === currentChatFriendId);
        if (friend) {
          selectContact(friend);
          clearInterval(checkFriend);
        }
      }
    }, 100);

    // 5秒后如果还没找到就清除定时器
    setTimeout(() => {
      clearInterval(checkFriend);
    }, 5000);
  }
});

</script>

<style scoped lang="scss">
.chat-container {
  height: 100vh;
  padding: 16px;
  background-color: #f5f7fa;
  max-width: 1600px;
  margin: 0 auto;
  box-sizing: border-box;
}

.contact-list {
  height: calc(100vh - 32px);
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 56px;
    padding: 0 16px;
    border-bottom: 1px solid #ebeef5;
    flex-shrink: 0;
    
    span {
      font-size: 16px;
      font-weight: 500;
      color: #303133;
      line-height: 56px;
    }
  }
  
  .el-scrollbar {
    flex: 1;
    overflow: hidden;
  }
  
  .contact-item {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    cursor: pointer;
    transition: all 0.3s ease;
    border-bottom: 1px solid #ebeef5;
    
    &:hover {
      background-color: #f5f7fa;
    }
    
    &.active {
      background-color: #ecf5ff;
    }
    
    .contact-info {
      margin-left: 12px;
      
      .contact-name {
        font-size: 14px;
        color: #303133;
      }
    }
  }
}

.chat-area {
  height: calc(100vh - 32px);
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  position: relative;
  
  .chat-header {
    display: flex;
    align-items: center;
    height: 56px;
    padding: 0 16px;
    border-bottom: 1px solid #ebeef5;
    background-color: #fff;
    flex-shrink: 0;
    z-index: 2;
    
    .contact-info {
      display: flex;
      align-items: center;
      height: 100%;
      
      .contact-name {
        margin-left: 12px;
        font-size: 16px;
        font-weight: 500;
        color: #303133;
        line-height: 56px;
      }
    }
  }
  
  .message-list {
    flex: 1;
    overflow-y: auto;
    padding: 16px;
    background-color: #f5f7fa;
    padding-bottom: 80px;
    height: calc(80% - 56px);
    position: absolute;
    top: 48%;
    left: 20px;
    right: 20px;
    transform: translateY(-50%);
    margin-top: 28px;
    border-radius: 8px;
    
    .message-item {
      display: flex;
      margin-bottom: 16px;
      max-width: 85%;
      margin-left: auto;
      margin-right: auto;
      
      &.message-mine {
        flex-direction: row-reverse;
        
        .message-content {
          margin-right: 12px;
          margin-left: 0;
          background-color: #ecf5ff;
          
          .message-text {
            text-align: right;
            max-width: 100%;
            word-break: break-word;
          }
          
          .message-time {
            text-align: right;
          }
        }
      }
      
      .message-content {
        margin-left: 12px;
        max-width: 85%;
        
        .message-text {
          padding: 12px;
          background-color: #fff;
          border-radius: 8px;
          word-break: break-word;
          box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
        }
        
        .message-time {
          margin-top: 4px;
          font-size: 12px;
          color: #909399;
        }
      }
    }
  }
  
  .message-input {
    padding: 16px;
    background-color: #fff;
    border-top: 1px solid #ebeef5;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 2;
    box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.05);
    height: 80px;  // 减小高度
    box-sizing: border-box;
    display: flex;  // 使用flex布局
    align-items: center;  // 垂直居中
    gap: 12px;  // 元素之间的间距
    
    .el-input {
      flex: 1;  // 文本框占据剩余空间
      margin-bottom: 0;  // 移除底部间距
    }
    
    .input-actions {
      flex-shrink: 0;  // 按钮不缩小
      
      .el-button {
        padding: 8px 20px;
        font-size: 14px;
      }
    }
  }
}

.e2ee-info {
  height: calc(100vh - 32px);
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  
  .card-header {
    height: 56px;
    padding: 0 16px;
    border-bottom: 1px solid #ebeef5;
    background-color: #fff;
    flex-shrink: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    
    .header-title {
      font-size: 16px;
      font-weight: 500;
      color: #303133;
      line-height: 56px;
    }
  }
  
  .info-content {
    flex: 1;
    overflow-y: auto;
    padding: 24px;  // 增加内边距
    background-color: #fff;
    
    ol {
      padding-left: 24px;  // 增加列表缩进
      margin-bottom: 24px;  // 增加底部间距
      
      li {
        margin-bottom: 20px;  // 增加列表项间距
        
        strong {
          color: #409EFF;
          display: block;
          margin-bottom: 12px;  // 增加标题底部间距
          font-size: 15px;
        }
        
        p {
          margin: 8px 0;
          color: #606266;
          font-size: 14px;
          line-height: 1.6;  // 增加行高
        }
        
        ul {
          padding-left: 24px;  // 增加子列表缩进
          margin: 12px 0;  // 增加子列表间距
          
          li {
            margin-bottom: 8px;  // 增加子列表项间距
            color: #606266;
            font-size: 14px;
            line-height: 1.6;  // 增加行高
          }
        }
      }
    }
    
    .security-tips {
      margin-top: 24px;  // 增加安全提示上边距
      
      p {
        margin: 12px 0;  // 增加段落间距
        color: #606266;
        font-size: 14px;
        line-height: 1.6;  // 增加行高
      }
    }
  }
}

// 响应式布局调整
@media screen and (max-width: 1600px) {
  .chat-container {
    padding: 12px;
  }
}

@media screen and (max-width: 1200px) {
  .chat-container {
    padding: 8px;
  }
  
  .contact-list {
    height: calc(100vh - 16px);
  }
  
  .chat-area {
    height: calc(100vh - 16px);
  }
  
  .e2ee-info {
    height: calc(100vh - 16px);
  }
}
</style> 